package jude.java.money.net.ftp;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.apache.commons.lang.StringUtils;

public abstract class AFtp {
	/** FTP文件路径分隔符 */
	public final static String separator = "/";
	public final static char separatorChar = '/';

	/** 本地文件路径分隔符 */
	public final static char localSeparator = File.separatorChar;

	/** 非本地文件路径分隔符的斜杆 */
	public final static char localSeparatorN = localSeparator == '\\' ? '/' : '\\';
	
	public final static int FTP_APACHE_COMMON_FTP = 1;
	public final static int FTP_JFTP = 2;
	public final static int FTP_SIMPLE_FTP = 3;
	public final static int FTP_DEFAULT = FTP_JFTP;

	protected String host;
	protected int port;
	protected String userName;
	protected String password;
	
	protected String rootPath;
	protected String pwd;
	
	public static AFtp get(int type, String ip, int port, String userName, String password) {
		switch (type) {
		case FTP_APACHE_COMMON_FTP:
			return new Ftp(ip, port, userName, password);
		case FTP_SIMPLE_FTP:
		default:
			break;
		}
		return get(FTP_DEFAULT, ip, port, userName, password);
	}
	public static AFtp get(int type, String ip, String userName, String password) {
		return get(type, ip, 21, userName, password);
	}
	public static AFtp get(String ip, String userName, String password) {
		return get(FTP_DEFAULT, ip, 21, userName, password);
	}

	protected AFtp(String ip, int port, String userName, String password) {
		this.host = ip;
		this.port = port;
		this.userName = userName;
		this.password = password;
	}

	/** FTP上路径以/分隔 */
	static String normalizeRemotePath(String remote) {
		if (remote.indexOf('\\') == -1)
			return remote;
		return remote.replace('\\', '/');
	}

	/** 本地文件路径格式化 */
	static String normalizeLocalPath(String local) {
		return local.replace(localSeparatorN, localSeparator);
	}

	/** 分割路路径与文件名 */
	static String[] split(String ftpFilePath) {
		ftpFilePath = normalizeRemotePath(ftpFilePath);
		if(ftpFilePath.endsWith(separator))
			ftpFilePath = StringUtils.substringBeforeLast(ftpFilePath, separator);
		if (!ftpFilePath.startsWith(separator))
			ftpFilePath = separator + ftpFilePath;
		String path = ftpFilePath.substring(0, ftpFilePath.lastIndexOf("/"));
		String fileName = ftpFilePath
				.substring(ftpFilePath.lastIndexOf("/") + 1);
		return new String[] { path, fileName };
	}
	
	protected void notSupport() {
		throw new RuntimeException("not support operator");
	}

	protected void finalize() throws Throwable {
		try {
			logout();
		} catch (Exception e) {
		}
	}

	// ///////////////////////////////////////////////////////////////////////////////////////
	/**是否已经建立连接*/
	public abstract boolean isConnected();
	/**登录*/
	public abstract boolean login();
	/**登出*/
	public abstract boolean logout();
	/**创建(完整)目录*/
	public abstract void buildPath(String path);
	
	public List<FtpFile> listFiles(String path) {
		notSupport();
		return null;
	}
	
	public List<FtpFile> listFiles() {
		return listFiles(null);
	}
	
	public boolean login(String usr, String pwd) {
		this.userName = usr;
		this.password = pwd;
		return this.login();
	}
	
	/**
	 * 上传目录
	 * @param file 文件夹的内容全部上传
	 * @param remote 上传到指定的目录
	 * a/b -> c/d => c/d
	 * */
	public abstract boolean uploadDirectory(File file, String remote) throws IOException;
	public  boolean uploadDirectory(String file, String remote) throws IOException{
		return uploadDirectory(new File(file), remote);
	}

	/**
	  * 上传文件
	*/
	public abstract boolean uploadFile(String local, String remote) throws IOException;
	public boolean uploadFile(File file, String remote) throws IOException{
		return uploadFile(file.getPath(), remote);
	}

	public abstract boolean downFile(String remote, String file) throws IOException;
	
	public abstract boolean downDirectory(String remote, String file) throws IOException;
	
	public abstract boolean deleteFile(String remote) throws IOException;
	
	/**删除空文件夹*/
	public abstract boolean deleteDirectory(String remote) throws IOException;
	
	public abstract boolean cd(String path);
	public boolean ccdd(String path){
		if(!cd(path)){
			buildPath(path);
			noop();
			return cd(path);
		}
		return true;
	}
	
	public abstract boolean exists(String file);
	
	public void noop(){
	}
	
	public void cmd(String cmd) {
		notSupport();
	}
	
	protected String decode(String str) {
		if (str == null)
			return str;
		int len = str.length();
		boolean f = false;
		for (int i=0; i<len; i++) {
			char c = str.charAt(i);
			if (c < '!' || c > '~') {
				f = true;
				break;
			}
		}
		if (f)
			try {
				return new String(str.getBytes("ISO-8859-1"), "GBK");
			} catch (Exception e) {
				e.printStackTrace();
			}
		return str;
	}
	
	/**assert*/
	public void assertTure(boolean v) {
		if(!v)
			throw new RuntimeException("Fail to execute the ftp command! make sure ...");
	}
	
	public void test() {
	}
	
	protected String pwd() {
		return null;
	}
}
